package cn.topevery.garden.dal.logic;

import cn.topevery.garden.dal.dao.EvaluationRulesDao;
import cn.topevery.garden.entity.po.EvaluationRules;
import cn.topevery.garden.entity.query.EvaluationRulesQuery;
import cn.topevery.garden.entity.vo.EvaluationRulesVO;
import cn.topevery.garden.entity.vo.EvaluationTableVO;
import cn.topevery.garden.entity.vo.EvaluationTreeVO;
import cn.topevery.garden.framework.base.BaseLogic;
import hw.topevery.framework.db.base.BaseEntityDao;
import hw.topevery.framework.db.entity.DataPager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 检查考评规则表
 *
 * @author code-generate
 * @date 2022-01-05
 */
@Service
public class EvaluationRulesLogic extends BaseLogic<EvaluationRules> {
    @Autowired
    EvaluationRulesDao evaluationRulesDao;

    @Override
    public BaseEntityDao<EvaluationRules, Integer> getDao() {
        return evaluationRulesDao;
    }

    

    /**
     * 获取列表
     *
     * @param query
     */
    public DataPager<EvaluationRulesVO> listPage(EvaluationRulesQuery query) {
        return evaluationRulesDao.listPage(query);
    }

    /**
     * 根据自增id批量删除
     *
     * @param ids
     */
    public void deleteBatchById(String userId,Integer[] ids) {
        evaluationRulesDao.delete(userId, ids);
    }

    /**
     * 根据自增id保存或者更新
     *
     * @param evaluationRules 实体
     */
    public void saveOrUpdate(String userId, EvaluationRules evaluationRules){
        evaluationRulesDao.saveOrUpdate(userId,evaluationRules);
    }

    /**
         * 根据自定义列值来获取对象
         */
    public EvaluationRules getEntityByColumn(String key, String value) {
        return evaluationRulesDao.getEntityByColumn(key, value);
    }

    public List<EvaluationRules> getRootList(){
        return evaluationRulesDao.getRootList();
    }

    public List<EvaluationRules> getListByPid(String pid){
        return evaluationRulesDao.getListByPid(pid);
    }

    public void commit(EvaluationRules rules, Integer userId){
        boolean isEdit = rules.getId() != null;
        rules.setDbUpdateDate(LocalDateTime.now());
        rules.setDbUpdateId(userId);
        if (rules.getLayer() == 0) {
            rules.setItemScore(0D);
        }
        if (rules.getLayer() == 1) {
            if (rules.getTotalScore() == null) {
                rules.setTotalScore(-1D);
                EvaluationRules byRuleId = evaluationRulesDao.getByRuleId(rules.getRulePid());
                byRuleId.setItemScore(-1.0);
                evaluationRulesDao.saveOrUpdate(userId.toString(),byRuleId);
            }else {
                Double changeTotalScore;
                if (isEdit) {
                    EvaluationRules oldRule = evaluationRulesDao.getByRuleId(rules.getRuleId());
                    changeTotalScore = rules.getTotalScore() - oldRule.getTotalScore();
                } else {
                    changeTotalScore = rules.getTotalScore();
                }
                evaluationRulesDao.updateItemScore(rules.getRulePid(), changeTotalScore);
            }
        }
        if (rules.getLayer() == 2 && rules.getDockScore() == null) {
            rules.setDockScore(-1D);
        }
        if (isEdit) {
            evaluationRulesDao.saveOrUpdate(userId.toString(),rules);
        } else {
            rules.setRuleId(UUID.randomUUID().toString());
            rules.setDbStatus(true);
            evaluationRulesDao.insert(userId.toString(),rules);
        }
    }

    public void deleteByRuleId(String ruleId, Integer layer, Integer userId){
        if (layer == 1) {
            EvaluationRules rule = evaluationRulesDao.getByRuleId(ruleId);
            evaluationRulesDao.updateItemScore(rule.getRulePid(), - rule.getTotalScore());
        }
//        evaluationRulesDao.deleteByRuleId(new EvaluationRules(), new UpdateWrapper<EvaluationRules>().lambda()
//                .eq(EvaluationRules::getRuleId, ruleId)
//                .set(EvaluationRules::getDbStatus, 1)
//                .set(EvaluationRules::getDbUpdateDate, LocalDateTime.now())
//                .set(EvaluationRules::getDbUpdateId, userId));
         evaluationRulesDao.deleteByRuleId(ruleId,layer,userId);
    }

    public EvaluationRules getByRuleId(String ruleId){
        return evaluationRulesDao.getByRuleId(ruleId);
    }

    public List<EvaluationTableVO> getEvaluationTable(Map<String, Object> map){
        List<EvaluationTableVO> list;
        if (map.get("tableId") != null) {
            list = evaluationRulesDao.getReportedEvaluationTable(map);
        } else {
            list = evaluationRulesDao.getEvaluationTable(map);
        }
        Map<String, List<EvaluationTableVO>> bigMap = list.stream()
                .collect(Collectors.groupingBy(EvaluationTableVO::getOneRuleId));
        Map<String, List<EvaluationTableVO>> smallMap;
        List<EvaluationTableVO> resultList = new ArrayList<>();
        List<EvaluationTableVO> tempList;
        List<EvaluationTableVO> tempList2;
        EvaluationTableVO vo;
        Double dockedScore;
        for (String oneRuleId : bigMap.keySet()) {
            smallMap = bigMap.get(oneRuleId).stream().collect(Collectors.groupingBy(EvaluationTableVO::getTwoRuleId));
            tempList = new ArrayList<>();
            for (String twoRuleId : smallMap.keySet()) {
                dockedScore = 0D;
                tempList2 = new ArrayList<>();
                for (int i = 0; i < smallMap.get(twoRuleId).size(); i++) {
                    vo = smallMap.get(twoRuleId).get(i);
                    if (i == 0) {
                        vo.setTwoRowSpan(smallMap.get(twoRuleId).size());
                        vo.setTwoColSpan(1);

                    } else {
                        vo.setTwoRowSpan(0);
                        vo.setTwoColSpan(0);
                    }
                    vo.setTotalScore(smallMap.get(twoRuleId).get(i).getTotalScore() == -1
                            ? 0f : smallMap.get(twoRuleId).get(i).getTotalScore());
                    vo.setOneRowSpan(0);
                    vo.setOneColSpan(0);
                    dockedScore += vo.getDockedScore();
                    vo.setScore(0D);
                    tempList2.add(vo);
                }
                if (tempList2.get(0).getTotalScore() != 0) {
                    tempList2.get(0).setScore(Math.max(tempList2.get(0).getTotalScore() - dockedScore, 0));
                } else {
                    tempList2.get(0).setScore(-dockedScore);
                }
                tempList.addAll(tempList2);
            }
            tempList.get(0).setOneColSpan(1);
            tempList.get(0).setOneRowSpan(tempList.size());
            resultList.addAll(tempList);
        }
        resultList = resultList.stream().sorted(Comparator.comparing(EvaluationTableVO::getOneOrder))
                .collect(Collectors.toList());
        return resultList;
    }

    public List<Map<String, Object>> getStatisticsTable(Map<String, Object> map){
        return evaluationRulesDao.getStatisticsTable(map);
    }

    public List<Map<String, Object>> getTotalScoreList(){
        return evaluationRulesDao.getTotalScoreList();
    }

    public List<Map<String, Object>> getStatisticsFormalTableByTableId(Integer tableId){
        return evaluationRulesDao.getStatisticsFormalTableByTableId(tableId);
    }



    public List<EvaluationTreeVO> getEvaluationTreeForMobile(Map<String, String> map){
        return evaluationRulesDao.getEvaluationTreeForMobile(map);
    }

}
